package ncsutest.util;
import com.sun.spot.peripheral.IDriver;
import com.sun.spot.peripheral.Spot;
import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ISwitch;
import com.sun.spot.sensorboard.peripheral.ISwitchListener;

public class Switches implements ISwitchListener, IDriver {
	public static final int IDLE = -2; 
	public static final int WAITING = -1; 
	public static final int BOTH = 0;
	public static final int LEFT = 1;
	public static final int RIGHT = 2;
	
	private ISwitch[] sws;
	private int state; // synchronized on sws
	private boolean dontSleep = false; // synchronized on this
	
	private static Switches SWITCHES = null;
	
	public synchronized static Switches getSwitches() {
		if (SWITCHES == null) SWITCHES = new Switches();
		return SWITCHES;
	}
	
	private Switches() {
		Spot.getInstance().getDriverRegistry().add(this);
		
		sws = EDemoBoard.getInstance().getSwitches();

		state = IDLE;
		sws[0].addISwitchListener(this);
		sws[1].addISwitchListener(this);
	}
	
	private void destroy() {
		sws[0].removeISwitchListener(this);
		sws[1].removeISwitchListener(this);
	}
	
	public int waitForSwitchRelease() {
		synchronized (this) { dontSleep = true; }
		
		int curState;
		synchronized (sws) {
			state = WAITING;
			try { sws.wait(); } catch (InterruptedException ie) {}
			curState = state;
			state = IDLE;
		}
		
		synchronized (this) { dontSleep = false; }
		
		return curState;
	}
	
	public void switchPressed(ISwitch sw) {
		synchronized (sws) {
			if (state == WAITING) {
				if (sws[0].isClosed() && sws[1].isClosed()) {
					state = BOTH;
				}
			}
		}
	}
	public void switchReleased(ISwitch sw) {
		synchronized (sws) {
			if (state == WAITING) {
				if (sw == sws[0]) state = LEFT;
				else			  state = RIGHT;
				sws.notifyAll();
			} else if (state == BOTH) {
				if (sws[0].isOpen() && sws[1].isOpen()) {
					sws.notifyAll();
				}
			}
		}
	}

	public String getDriverName() {return "Switches";}
	public synchronized boolean tearDown() { return !dontSleep; }
	public void setUp() {}
	public void shutDown() {}
}